/*
 * @Author: secrets123
 * @Date: 2022-07-21 10:53:28
 * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @LastEditTime: 2023-10-17 10:25:02
 * @FilePath: \stm32g431_AllRings\libraries\HAL_Drivers\my_fdcan_drv.c
 * @Description:
 *
 * Copyright (c) 2022 by secrets123 1097290967@qq.com, All Rights Reserved.
 */
#include <rtthread.h>
#include <rtconfig.h>
#include <board.h>
#include "my_fdcan_drv.h"
#include "iap_para.h"

#define DRV_DEBUG
#define LOG_TAG "drv.myfdcan"
#include <drv_log.h>

uint8_t all_can_rx_startflag = 0;

FDCAN_HandleTypeDef hfdcan1;
FDCAN_TxHeaderTypeDef TxHeader1;
FDCAN_RxHeaderTypeDef RxHeader1;

/**/
const uint8_t CRCHTable[] = // CRC 高位字节值表
    {
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
        0x00, 0xC1, 0x81, 0x40};
const uint8_t CRCLTable[] = // CRC 低位字节值表
    {
        0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
        0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
        0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
        0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
        0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
        0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
        0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
        0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
        0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
        0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
        0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
        0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
        0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
        0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
        0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
        0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
        0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
        0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
        0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
        0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
        0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
        0x41, 0x81, 0x80, 0x40};

uint16_t CRC16(uint8_t *pchMsg, int16_t wDataLen)
{
    uint8_t chCRCHi = 0xFF; // 高CRC字节初始化
    uint8_t chCRCLo = 0xFF; // 低CRC字节初始化
    int16_t wIndex;         // CRC循环中的索引
    while (wDataLen--)
    {
        // 计算CRC
        wIndex = chCRCHi ^ *pchMsg++;
        chCRCHi = chCRCLo ^ CRCHTable[wIndex];
        chCRCLo = CRCLTable[wIndex];
    }
    return ((chCRCHi << 8) | chCRCLo);
}

/**
 * @brief FDCAN1 Initialization Function
 * @param None
 * @retval None
 */
int MX_FDCAN_Init(void)
{

    /* USER CODE BEGIN FDCAN1_Init 0 */

    /* USER CODE END FDCAN1_Init 0 */

    /* USER CODE BEGIN FDCAN1_Init 1 */

    /* USER CODE END FDCAN1_Init 1 */
    // fdcan1-init
    hfdcan1.Instance = FDCAN1;
    hfdcan1.Init.ClockDivider = FDCAN_CLOCK_DIV2;
    hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_NO_BRS;
    hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;
    hfdcan1.Init.AutoRetransmission = ENABLE;
    hfdcan1.Init.TransmitPause = DISABLE;
    hfdcan1.Init.ProtocolException = DISABLE;
    hfdcan1.Init.NominalPrescaler = 5;
    hfdcan1.Init.NominalSyncJumpWidth = 4;
    hfdcan1.Init.NominalTimeSeg1 = 12;
    hfdcan1.Init.NominalTimeSeg2 = 4;
    hfdcan1.Init.DataPrescaler = 5;
    hfdcan1.Init.DataSyncJumpWidth = 4;
    hfdcan1.Init.DataTimeSeg1 = 12;
    hfdcan1.Init.DataTimeSeg2 = 4;
    hfdcan1.Init.StdFiltersNbr = 2;
    hfdcan1.Init.ExtFiltersNbr = 0;
    hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; // FDCAN_TX_FIFO_OPERATION;
    if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
    {
        Error_Handler();
    }
    //    // fdcan2-init
    //    hfdcan2.Instance = FDCAN2;
    //    hfdcan2.Init.ClockDivider = FDCAN_CLOCK_DIV2;
    //    hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
    //    hfdcan2.Init.Mode = FDCAN_MODE_NORMAL;
    //    hfdcan2.Init.AutoRetransmission = ENABLE;
    //    hfdcan2.Init.TransmitPause = ENABLE;
    //    hfdcan2.Init.ProtocolException = DISABLE;
    //    hfdcan2.Init.NominalPrescaler = 5;
    //    hfdcan2.Init.NominalSyncJumpWidth = 4;
    //    hfdcan2.Init.NominalTimeSeg1 = 12;
    //    hfdcan2.Init.NominalTimeSeg2 = 4;
    //    hfdcan2.Init.DataPrescaler = 5;
    //    hfdcan2.Init.DataSyncJumpWidth = 4;
    //    hfdcan2.Init.DataTimeSeg1 = 12;
    //    hfdcan2.Init.DataTimeSeg2 = 4;
    //    hfdcan2.Init.StdFiltersNbr = 1;
    //    hfdcan2.Init.ExtFiltersNbr = 0;
    //    hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
    //    if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)
    //    {
    //        Error_Handler();
    //    }
    /* USER CODE BEGIN FDCAN1_Init 2 */
    fdcan1_filter_config();
    //    fdcan2_filter_config();
    /* USER CODE END FDCAN1_Init 2 */

    return 0;
}
INIT_PREV_EXPORT(MX_FDCAN_Init);
// INIT_BOARD_EXPORT(MX_FDCAN_Init);

void FDCAN_Transmit(FDCAN_HandleTypeDef *hfdcan, uint32_t id, uint16_t data_length, uint8_t *fdcandata)
{
    FDCAN_TxHeaderTypeDef *TxHeader;

    if (hfdcan->Instance == FDCAN1)
    {
        TxHeader = &TxHeader1;
    }
    else
    {
        TxHeader = &TxHeader1;
    }

    //    TxHeader->Identifier = allrings_paras.allsys_para.can_id;
    switch (data_length)
    {
    case 0:
        TxHeader->DataLength = FDCAN_DLC_BYTES_0;
        break;
    case 1:
        TxHeader->DataLength = FDCAN_DLC_BYTES_1;
        break;
    case 2:
        TxHeader->DataLength = FDCAN_DLC_BYTES_2;
        break;
    case 3:
        TxHeader->DataLength = FDCAN_DLC_BYTES_3;
        break;
    case 4:
        TxHeader->DataLength = FDCAN_DLC_BYTES_4;
        break;
    case 5:
        TxHeader->DataLength = FDCAN_DLC_BYTES_5;
        break;
    case 6:
        TxHeader->DataLength = FDCAN_DLC_BYTES_6;
        break;
    case 7:
        TxHeader->DataLength = FDCAN_DLC_BYTES_7;
        break;
    case 8:
        TxHeader->DataLength = FDCAN_DLC_BYTES_8;
        break;
    case 9:
        TxHeader->DataLength = FDCAN_DLC_BYTES_12;
        break;
    case 10:
        TxHeader->DataLength = FDCAN_DLC_BYTES_16;
        break;
    case 11:
        TxHeader->DataLength = FDCAN_DLC_BYTES_20;
        break;
    case 12:
        TxHeader->DataLength = FDCAN_DLC_BYTES_24;
        break;
    case 13:
        TxHeader->DataLength = FDCAN_DLC_BYTES_32;
        break;
    case 14:
        TxHeader->DataLength = FDCAN_DLC_BYTES_48;
        break;
    case 15:
        TxHeader->DataLength = FDCAN_DLC_BYTES_64;
        break;
    default:
        TxHeader->DataLength = FDCAN_DLC_BYTES_0;
        break;
    }

    // 获取到接收标志后,开启发送
    extern uint8_t all_can_rx_startflag;
    if (all_can_rx_startflag)
    {
        if (HAL_FDCAN_AddMessageToTxFifoQ(hfdcan, TxHeader, fdcandata) != HAL_OK)
        {
            // Error_Handler(); //发送错误，会进入hardfault中断，后期需要处理，保证系统的健壮性
        }
    }
}

void FDCAN1_IT0_IRQHandler(void)
{
    /* enter interrupt */
    rt_interrupt_enter();

    HAL_FDCAN_IRQHandler(&hfdcan1);

    /* leave interrupt */
    rt_interrupt_leave();
}

// fdcan1接收数据回调函数
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
    extern void rt_fdcan1_irq_feedback(void *user, uint8_t *pdata);
    extern void rt_fdcan2_irq_feedback(void *user, uint8_t *pdata);

    static uint8_t RxDATA[64] = {0};
    uint8_t tempdata[8] = {0};

    if (hfdcan->Instance == FDCAN1)
    {
        if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != 0)
        {
            all_can_rx_startflag = 1;                                           // can设备获取到，允许发送总使能
            HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader1, RxDATA); // 接收fdcan数据，放入结构体中
            TxHeader1.FDFormat = RxHeader1.FDFormat;
            if ((RxHeader1.Identifier == 0x1ff) ||
                (RxHeader1.Identifier == 0x2ff) ||
                (RxHeader1.Identifier == 0x3ff))
            {
                uint16_t new_crc, old_crc;
                if (RxHeader1.DataLength > FDCAN_DLC_BYTES_1)
                {
                    old_crc = RxDATA[62] << 8 | RxDATA[63];
                    new_crc = CRC16(RxDATA, 62);
                    if ((new_crc == old_crc) && (allrings_paras.allsys_para.canfd_broadcast_index <= 7))
                    {
                        for (uint8_t i = 0; i < 8; i++)
                            RxDATA[0 + i] = RxDATA[allrings_paras.allsys_para.canfd_broadcast_index * 8 + i];
                        RxHeader1.DataLength = FDCAN_DLC_BYTES_8;
                        rt_fdcan1_irq_feedback(&RxHeader1, RxDATA);
                    }
                }
            }
            else
                rt_fdcan1_irq_feedback(&RxHeader1, RxDATA);
        }
    }
}

// void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo1ITs)
// {
//     extern void rt_fdcan2_irq_feedback(void *user, uint8_t *pdata);
//     static uint8_t RxDATA[64] = {0};

//     if ((RxFifo1ITs & FDCAN_IT_RX_FIFO1_NEW_MESSAGE) != 0)
//     {
//         HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO1, &RxHeader2, RxDATA); //接收fdcan数据，放入结构体中

//         rt_fdcan2_irq_feedback(&RxHeader2, RxDATA);
//     }
// }
// void rt_fdcan_irq_feedback(void *user, uint8_t *pdata)
// {
//     static struct _fdcan1_rxdata fdcan1_rx = {0};
//     static FDCAN_RxHeaderTypeDef *rx_header;

//     rx_header = (FDCAN_RxHeaderTypeDef *)user;
//     fdcan1_rx.dta_length = RxHeader.DataLength >> 16;

//     rt_mq_send(fdcan1_msg, &fdcan1_rx, sizeof(struct _fdcan1_rxdata));

//     fdcan_rxirq_num++;
//     // LOG_I("fdcan rx %d messenge:%x !\r\n", fdcan1_rx.dta_length, fdcan1_rx.data);
// }

// 错误中断回调函数
void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t ErrorStatusITs)
{
    if (hfdcan->Instance == FDCAN1)
    {
        MX_FDCAN_Init();
        // fdcan1_filter_config();
    }
    else
    {
        ;
    }
}

FDCAN_FilterTypeDef _sFilterConfig1;
// FDCAN_FilterTypeDef _sFilterConfig2;
void fdcan1_filter_config(void)
{
    /* Configure Rx filter */
    _sFilterConfig1.IdType = FDCAN_STANDARD_ID;
    _sFilterConfig1.FilterIndex = 0;
    _sFilterConfig1.FilterType = FDCAN_FILTER_DUAL;
    _sFilterConfig1.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
    if (allrings_paras.allsys_para.can_id)
        _sFilterConfig1.FilterID1 = allrings_paras.allsys_para.can_id; //   0x72;
    else
        _sFilterConfig1.FilterID1 = 0x72;
    _sFilterConfig1.FilterID2 = 0x1ff;

    if (HAL_FDCAN_ConfigFilter(&hfdcan1, &_sFilterConfig1) != HAL_OK)
    {
        Error_Handler();
    }
    /* 调用滤波全局设置 */
    HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, ENABLE, ENABLE);

    _sFilterConfig1.IdType = FDCAN_STANDARD_ID;
    _sFilterConfig1.FilterIndex = 1;
    _sFilterConfig1.FilterType = FDCAN_FILTER_DUAL;
    _sFilterConfig1.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
    _sFilterConfig1.FilterID1 = 0x2ff;
    _sFilterConfig1.FilterID2 = 0x3ff;
    if (HAL_FDCAN_ConfigFilter(&hfdcan1, &_sFilterConfig1) != HAL_OK)
    {
        Error_Handler();
    }
    /* 调用滤波全局设置 */
    HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, ENABLE, ENABLE);

    /* 配置接收 FIFO 0 watermark 为 2 */
    // HAL_FDCAN_ConfigFifoWatermark(&hfdcan1, FDCAN_CFG_RX_FIFO0, 2);

    /* 使能FDCAN接收中断 */
    HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);

    /* Prepare Tx Header */
    // TxHeader1.Identifier = 0x72;
    if (allrings_paras.allsys_para.can_id)
        TxHeader1.Identifier = allrings_paras.allsys_para.can_id; //   0x72;
    else
        TxHeader1.Identifier = 0x72;
    TxHeader1.IdType = FDCAN_STANDARD_ID;
    TxHeader1.TxFrameType = FDCAN_DATA_FRAME;
    TxHeader1.DataLength = FDCAN_DLC_BYTES_0;
    TxHeader1.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
    TxHeader1.BitRateSwitch = FDCAN_BRS_OFF;
    TxHeader1.FDFormat = FDCAN_CLASSIC_CAN; // FDCAN_FD_CAN;
    TxHeader1.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
    TxHeader1.MessageMarker = 0;

    HAL_FDCAN_Start(&hfdcan1);

    // LOG_I("FDCAN Filter init finished! \r\n");
}
void CANIO_UpdateID(uint8_t _id)
{
    _sFilterConfig1.IdType = FDCAN_STANDARD_ID;
    _sFilterConfig1.FilterIndex = 0;
    _sFilterConfig1.FilterType = FDCAN_FILTER_DUAL;
    _sFilterConfig1.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
    _sFilterConfig1.FilterID1 = _id;
    _sFilterConfig1.FilterID2 = 0x1ff;

    if (HAL_FDCAN_ConfigFilter(&hfdcan1, &_sFilterConfig1) != HAL_OK)
    {
        // CANIO_Error_Handler();
    }
    TxHeader1.Identifier = allrings_paras.allsys_para.can_id;
}
/***************************************************************************************************************************/
// static uint32_t HAL_RCC_FDCAN_CLK_ENABLED = 0;

// /**
//  * @brief FDCAN MSP Initialization
//  * This function configures the hardware resources used in this example
//  * @param hfdcan: FDCAN handle pointer
//  * @retval None
//  */
// void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef *hfdcan)
// {
//     GPIO_InitTypeDef GPIO_InitStruct = {0};
//     RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
//     if (hfdcan->Instance == FDCAN1)
//     {
//         /* USER CODE BEGIN FDCAN1_MspInit 0 */

//         /* USER CODE END FDCAN1_MspInit 0 */
//         /** Initializes the peripherals clocks
//          */
//         PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
//         PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PCLK1;
//         if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
//         {
//             Error_Handler();
//         }

//         /* Peripheral clock enable */
//         HAL_RCC_FDCAN_CLK_ENABLED++;
//         if (HAL_RCC_FDCAN_CLK_ENABLED == 1)
//         {
//             __HAL_RCC_FDCAN_CLK_ENABLE();
//         }

//         __HAL_RCC_GPIOA_CLK_ENABLE();
//         /**FDCAN1 GPIO Configuration
//         PA11     ------> FDCAN1_RX
//         PA12     ------> FDCAN1_TX
//         */
//         GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
//         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
//         GPIO_InitStruct.Pull = GPIO_NOPULL;
//         GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//         GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN1;
//         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

//         /* FDCAN1 interrupt Init */
//         HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn, 1, 0);
//         HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn);
//         LOG_D("set fdcan priority ok!\r\n");
//         /* USER CODE BEGIN FDCAN1_MspInit 1 */

//         /* USER CODE END FDCAN1_MspInit 1 */
//     }
//     else if (hfdcan->Instance == FDCAN2)
//     {
//         /* USER CODE BEGIN FDCAN2_MspInit 0 */

//         /* USER CODE END FDCAN2_MspInit 0 */

//         /** Initializes the peripherals clocks
//          */
//         PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
//         PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PCLK1;
//         if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
//         {
//             Error_Handler();
//         }

//         /* Peripheral clock enable */
//         HAL_RCC_FDCAN_CLK_ENABLED++;
//         if (HAL_RCC_FDCAN_CLK_ENABLED == 1)
//         {
//             __HAL_RCC_FDCAN_CLK_ENABLE();
//         }

//         __HAL_RCC_GPIOB_CLK_ENABLE();
//         /**FDCAN2 GPIO Configuration
//         PB5     ------> FDCAN2_RX
//         PB6     ------> FDCAN2_TX
//         */
//         GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6;
//         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
//         GPIO_InitStruct.Pull = GPIO_NOPULL;
//         GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
//         GPIO_InitStruct.Alternate = GPIO_AF9_FDCAN2;
//         HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

//         /* USER CODE BEGIN FDCAN2_MspInit 1 */

//         /* USER CODE END FDCAN2_MspInit 1 */
//     }
// }

// /**
//  * @brief FDCAN MSP De-Initialization
//  * This function freeze the hardware resources used in this example
//  * @param hfdcan: FDCAN handle pointer
//  * @retval None
//  */
// void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef *hfdcan)
// {
//     if (hfdcan->Instance == FDCAN1)
//     {
//         /* USER CODE BEGIN FDCAN1_MspDeInit 0 */

//         /* USER CODE END FDCAN1_MspDeInit 0 */
//         /* Peripheral clock disable */
//         HAL_RCC_FDCAN_CLK_ENABLED--;
//         if (HAL_RCC_FDCAN_CLK_ENABLED == 0)
//         {
//             __HAL_RCC_FDCAN_CLK_DISABLE();
//         }

//         /**FDCAN1 GPIO Configuration
//         PA11     ------> FDCAN1_RX
//         PA12     ------> FDCAN1_TX
//         */
//         HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11 | GPIO_PIN_12);

//         /* FDCAN1 interrupt DeInit */
//         HAL_NVIC_DisableIRQ(FDCAN1_IT0_IRQn);
//         /* USER CODE BEGIN FDCAN1_MspDeInit 1 */

//         /* USER CODE END FDCAN1_MspDeInit 1 */
//     }
//     else if (hfdcan->Instance == FDCAN2)
//     {
//         /* USER CODE BEGIN FDCAN2_MspDeInit 0 */

//         /* USER CODE END FDCAN2_MspDeInit 0 */
//         /* Peripheral clock disable */
//         HAL_RCC_FDCAN_CLK_ENABLED--;
//         if (HAL_RCC_FDCAN_CLK_ENABLED == 0)
//         {
//             __HAL_RCC_FDCAN_CLK_DISABLE();
//         }

//         /**FDCAN2 GPIO Configuration
//         PB5     ------> FDCAN2_RX
//         PB6     ------> FDCAN2_TX
//         */
//         HAL_GPIO_DeInit(GPIOB, GPIO_PIN_5 | GPIO_PIN_6);

//         /* USER CODE BEGIN FDCAN2_MspDeInit 1 */

//         /* USER CODE END FDCAN2_MspDeInit 1 */
//     }
// }
